home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / GRAPHICS.SWG / 0046_3D Rotation.pas < prev    next >
Pascal/Delphi Source File  |  1994-01-27  |  6KB  |  203 lines

  1. program BoxRot;
  2.  
  3. {PUBLIC DOMAIN  1993 Peter M. Gruhn
  4.  
  5. Program draws a box on screen. Allows user to rotate the box around
  6. the three primary axes. Viewing transform is simple ignore z.
  7.  
  8. I used _Computer_Graphics:_Principles_and_Practice_, Foley et al
  9. ISBN 0-201-12110-7 as a reference
  10.  
  11. RUNNING:
  12. Borland Pascal 7. Should run on any graphics device supported by BGI.
  13. If you have smaller than 280 resolution, change '+200' to something
  14. smaller and/or change 75 to something smaller.
  15.  
  16. Since this machine is
  17. not really set up for doing DOS graphics, I hard coded my BGI path, so
  18. you have to find 'initgraph' and change the bgi path to something that
  19. works on your machine. Try ''.
  20.  
  21. Okey dokey. This is kinda slow, and does a nice job of demonstrating the
  22. problems of repeatedly modifying the same data set. That is, the more and
  23. more you rotate the box, the more and more distorted it gets. This is
  24. because computers are not perfect at calculations, and all of those little
  25. errors add up quite quickly.
  26.  
  27. It's because of that that I used reals, not reals. I used floating point
  28. because the guy doesn't know what is going on at all with 3d, so better to
  29. look at only the math that is really happening. Besides, I still have to
  30. think to use fixed point. Whaddaya want for .5 hour programming.
  31.  
  32.  DIRECTIONS:
  33.    ',' - rotates around the x axis
  34.    '.' - rotates around the y axis
  35.    '/' - rotates around the z axis
  36.    'q' - quits
  37.  
  38.    All rotations are done around global axes, not object axes.
  39. }
  40.  
  41. uses
  42.   graph,
  43.   crt;
  44.  
  45. const
  46.   radtheta = 1 {degrees} * 3.1415926535 {radians} / 180 {per degrees};
  47.   { sin and cos on computers are done in radians. }
  48.  
  49. type
  50.   tpointr = record   { Just a record to hold 3d points }
  51.     x, y, z : real;
  52.   end;
  53.  
  54. var
  55.   box : array [0..7] of tpointr;   { The box we will manipulate }
  56.   c   : char;                      { Our input mechanism }
  57.  
  58. procedure init;
  59. var
  60.   gd, gm : integer;
  61. { turns on graphics and creates a cube. Since the rotation routines
  62.   rotate around the origin, I have centered the cube on the origin, so
  63.   that it stays in place and only spins. }
  64. begin
  65.   gd := detect;
  66.   initgraph(gd, gm, 'e:\bp\bgi');
  67.   box[0].x := -75;  box[0].y := -75;  box[0].z := -75;
  68.   box[1].x := 75;   box[1].y := -75;  box[1].z := -75;
  69.   box[2].x := 75;   box[2].y := 75;   box[2].z := -75;
  70.   box[3].x := -75;  box[3].y := 75;   box[3].z := -75;
  71.   box[4].x := -75;  box[4].y := -75;  box[4].z := 75;
  72.   box[5].x := 75;   box[5].y := -75;  box[5].z := 75;
  73.   box[6].x := 75;   box[6].y := 75;   box[6].z := 75;
  74.   box[7].x := -75;  box[7].y := 75;   box[7].z := 75;
  75. end;
  76.  
  77. procedure myline(x1, y1, z1, x2, y2, z2 : real);
  78. { Keeps the draw routine pretty. Pixels are integers, so I round. Since the
  79.  cube is centered around 0,0 I move it over 200 to put it on screen. }
  80. begin
  81. { if you think those real mults are slow, here's some rounds too... hey, you
  82.   may wonder, what happened to the stinking z coordinate? Ah, says I, this
  83.   is the simplest of 3d viewing transforms. You just take the z coord out of
  84.   things and boom. Looking straight down the z axis on the object. If I get
  85.   inspired, I will add simple perspective transform to these.  There, got
  86.   inspired. Made mistakes. Foley et al are not very good at tutoring
  87.   perspective and I'm kinda ready to be done and post this. }
  88.   line(round(x1) + 200, round(y1) + 200, round(x2) + 200, round(y2) + 200);
  89. end;
  90.  
  91. procedure draw;
  92. { my model is hard coded. No cool things like vertex and edge and face lists.}
  93. begin
  94.   myline(box[0].x, box[0].y, box[0].z, box[1].x, box[1].y, box[1].z);
  95.   myline(box[1].x, box[1].y, box[1].z, box[2].x, box[2].y, box[2].z);
  96.   myline(box[2].x, box[2].y, box[2].z, box[3].x, box[3].y, box[3].z);
  97.   myline(box[3].x, box[3].y, box[3].z, box[0].x, box[0].y, box[0].z);
  98.  
  99.   myline(box[4].x, box[4].y, box[4].z, box[5].x, box[5].y, box[5].z);
  100.   myline(box[5].x, box[5].y, box[5].z, box[6].x, box[6].y, box[6].z);
  101.   myline(box[6].x, box[6].y, box[6].z, box[7].x, box[7].y, box[7].z);
  102.   myline(box[7].x, box[7].y, box[7].z, box[4].x, box[4].y, box[4].z);
  103.  
  104.   myline(box[0].x, box[0].y, box[0].z, box[4].x, box[4].y, box[4].z);
  105.   myline(box[1].x, box[1].y, box[1].z, box[5].x, box[5].y, box[5].z);
  106.   myline(box[2].x, box[2].y, box[2].z, box[6].x, box[6].y, box[6].z);
  107.   myline(box[3].x, box[3].y, box[3].z, box[7].x, box[7].y, box[7].z);
  108.  
  109.   myline(box[0].x, box[0].y, box[0].z, box[5].x, box[5].y, box[5].z);
  110.   myline(box[1].x, box[1].y, box[1].z, box[4].x, box[4].y, box[4].z);
  111. end;
  112.  
  113. procedure rotx;
  114. {if you know your matrix multiplication, the following equations
  115.  are derived from
  116.  
  117.  [x   [ 1  0  0  0   [x',y',z',1]
  118.   y     0  c -s  0 =
  119.   z     0  s  c  0
  120.   1]    0  0  0  1]
  121. }
  122. var
  123.   i : integer;
  124. begin
  125.   setcolor(0);
  126.   draw;
  127.   for i := 0 to 7 do
  128.   begin
  129.     box[i].x :=  box[i].x;
  130.     box[i].y :=  box[i].y * cos(radTheta) + box[i].z * sin(radTheta);
  131.     box[i].z := -box[i].y * sin(radTheta) + box[i].z * cos(radTheta);
  132.   end;
  133.   setcolor(15);
  134.   draw;
  135. end;
  136.  
  137. procedure roty;
  138. {if you know your matrix multiplication, the following equations
  139.  are derived from
  140.  
  141.  [x   [ c  0  s  0   [x',y',z',1]
  142.   y     0  1  0  0 =
  143.   z    -s  0  c  0
  144.   1]    0  0  0  1]
  145. }
  146. var
  147.   i : integer;
  148. begin
  149.   setcolor(0);
  150.   draw;
  151.   for i := 0 to 7 do
  152.   begin
  153.     box[i].x := box[i].x * cos(radTheta) - box[i].z * sin(radTheta);
  154.     box[i].y := box[i].y;
  155.     box[i].z := box[i].x * sin(radTheta) + box[i].z * cos(radTheta);
  156.   end;
  157.   setcolor(15);
  158.   draw;
  159. end;
  160.  
  161. procedure rotz;
  162. {if you know your matrix multiplication, the following equations
  163.  are derived from
  164.  
  165.  [x   [ c -s  0  0   [x',y',z',1]
  166.   y     s  c  0  0 =
  167.   z     0  0  1  0
  168.   1]    0  0  0  1]
  169. }
  170. var
  171.   i : integer;
  172. begin
  173.   setcolor(0);
  174.   draw;
  175.   for i := 0 to 7 do
  176.   begin
  177.     box[i].x :=  box[i].x * cos(radTheta) + box[i].y * sin(radTheta);
  178.     box[i].y := -box[i].x * sin(radTheta) + box[i].y * cos(radTheta);
  179.     box[i].z :=  box[i].z;
  180.   end;
  181.   setcolor(15);
  182.   draw;
  183. end;
  184.  
  185.  
  186. begin
  187.   init;
  188.   setcolor(14);
  189.   draw;
  190.   repeat
  191.     c := readkey;
  192.     case c of
  193.       ',' : rotx;
  194.       '.' : roty;
  195.       '/' : rotz;
  196.       else {who gives a};
  197.     end; {case}
  198.   until c = 'q';
  199.   closegraph;
  200. end.
  201.  
  202.  
  203.